home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 142
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan).7z
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan) (Track 1).bin
/
tools
/
s44play
/
s44p101s.lzh
/
scsicmd.s
< prev
next >
Wrap
Text File
|
1999-12-19
|
9KB
|
372 lines
.include iocscall.mac
.include global.mac
;----------------------------------------------------------------
;SCSIコマンド発行
;<(4,sp).l:CDBの長さ(バイト)
;<(8,sp).l:CDBの先頭アドレス
;<(12,sp).l:読み込みバッファの長さ
;<(16,sp).l:読み込みバッファの先頭アドレス
;>d0.l:下位ワード=_S_STSINの結果,上位ワード=_S_MSGINの結果,負数=エラー
;>n-flag:mi=エラー
.offset -4
frmsiz:
msgsts:
.ds.b 1
msg: .ds.b 1
.ds.b 1
sts: .ds.b 1
_a6: .ds.l 1
_pc: .ds.l 1
cdblen: .ds.l 1
cdbptr: .ds.l 1
buflen: .ds.l 1
bufptr: .ds.l 1
.text
.align 4,$2048
scsicmd::
link a6,#frmsiz
movem.l d1-d4/d6-d7/a1,-(sp)
; bsr super
bsr scsi_hard_soft_on
st.b scsicmd_in_progress
clr.b scsicmd_error_retry
moveq.l #SCSI_READ_RETRY_COUNT-1,d7
7:
move.l scsiid,d4 ;lun,id
moveq.l #_S_SELECT,d6
SCSI _S_SELECT
tst.l d0
bne 89f ;0以外なら異常終了
movea.l (cdbptr,a6),a1
move.w scsiid,d0 ;lun
lsl.b #5,d0
andi.b #$1F,(1,a1)
or.b d0,(1,a1)
move.l (cdblen,a6),d3
move.l scsiid,d4 ;lun,id
moveq.l #_S_CMDOUT,d6
SCSI _S_CMDOUT
tst.l d0
bmi 89f ;0でなくてもよい
move.l (buflen,a6),d3
beq 3f
movea.l (bufptr,a6),a1
tst.b hard_soft
bgt 1f ;設定がなければ_S_DATAINを使う
moveq.l #_S_DATAIN,d6
SCSI _S_DATAIN ;ハード転送
bra 2f
1: moveq.l #_S_DATAIN_P,d6
SCSI _S_DATAIN_P ;ソフト転送
2: tst.l d0
bmi 89f ;0でなくてもよい
3:
clr.l (msgsts,a6)
lea.l (sts,a6),a1
moveq.l #_S_STSIN,d6
SCSI _S_STSIN
tst.l d0
bne 89f
lea.l (msg,a6),a1
moveq.l #_S_MSGIN,d6
SCSI _S_MSGIN
tst.l d0
bne 89f
move.l (msgsts,a6),d1
moveq.l #-1,d6
bsr scsistssns ;ステータスバイトとセンスキーをチェック
beq 99f
bmi 89f
addq.b #1,scsicmd_error_retry
dbra d7,7b ;リトライする
moveq.l #-2,d6
89: move.b d6,scsicmd_error_call
move.l d0,scsicmd_error_d0
moveq.l #-1,d1
99: sf.b scsicmd_in_progress
bsr scsi_hard_soft_off
; bsr user
move.l d1,d0
movem.l (sp)+,d1-d4/d6-d7/a1
unlk a6
rts
.data
scsicmd_in_progress:: .dc.b 0 ;-1=SCSI転送処理中
scsicmd_error_retry: .dc.b 0
scsicmd_error_call:: .dc.b 0 ;-1=エラー(リトライ可),-2=エラー(リトライ不可)
.align 4
scsicmd_error_d0: .dc.l 0
scsiid:: .dc.l -1 ;lun,id
;----------------------------------------------------------------
;_S_MODESELECT実行
;<d3.l:CDBの長さ(バイト)
;<a1.l:CDBの先頭アドレス
;>d0.l:下位ワード=_S_STSINの結果,上位ワード=_S_MSGINの結果,負数=エラー
;>n-flag:mi=エラー
.text
.align 4,$2048
modeselect::
movem.l d1-d4/d6-d7/a1,-(sp)
; bsr super
bsr scsi_hard_soft_on
st.b scsicmd_in_progress
clr.b scsicmd_error_retry
moveq.l #MODESELECT_RETRY_COUNT-1,d7
7:
moveq.l #$10,d2 ;PF=1(ページフォーマット),SP=0(セーブページなし)
move.l (4*2,sp),d3 ;スタックオフセット注意
move.l scsiid,d4 ;lun,id
movea.l (4*6,sp),a1 ;スタックオフセット注意
moveq.l #_S_MODESELECT,d6
SCSI _S_MODESELECT
move.l d0,d1
bmi 89f
moveq.l #-1,d6
bsr scsistssns ;ステータスバイトとセンスキーをチェック
beq 99f
bmi 89f
addq.b #1,scsicmd_error_retry
dbra d7,7b ;リトライする
moveq.l #-2,d6
89: move.b d6,scsicmd_error_call
move.l d0,scsicmd_error_d0
moveq.l #-1,d1
99: sf.b scsicmd_in_progress
bsr scsi_hard_soft_off
; bsr user
move.l d1,d0
movem.l (sp)+,d1-d4/d6-d7/a1
rts
;----------------------------------------------------------------
;SCSIコマンドの後処理
; ステータスバイトを解析してエラーやリトライの判定を行う
;<d1.l:下位ワード=_S_STSINの結果,上位ワード=_S_MSGINの結果,負数=エラー
;>d0.l:0=正常終了,1=エラー(リトライ可),-1=エラー(リトライ不可)
;>z-flag:eq=正常終了,ne=エラー
;>n-flag:(ne)pl=リトライ可,mi=リトライ不可
.text
.align 4,$2048
scsistssns::
movem.l d1-d4/a1,-(sp)
lea.l (-256,sp),sp
moveq.l #$3E,d0
and.b d1,d0 ;ステータスバイト
move.b d0,scsicmd_error_sts
; $00 Good → 正常終了
; $02 Check Condition → Request Senseを発行しなければならない
; $04 Condition Met
; $08 Busy → リトライ
; $10 Intermediate
; $14 Intermediate-Condition Met
; $18 Reservation Conflict
; $22 Command Terminated
; $28 Queue Full
; その他 → エラー
beq 8f ;$00 → 正常終了
subq.b #$02,d0
beq 1f ;$02 → Request Sense
subq.b #$08-$02,d0
beq 7f ;$08 → リトライ
bra 6f
1: moveq.l #26,d3
move.l scsiid,d4 ;lun,id
movea.l sp,a1
SCSI _S_REQUEST
moveq.l #$0F,d0
and.b (2,sp),d0 ;センスキー
move.b d0,scsicmd_error_sns
; $0 No Sense → 正常終了
; $1 Recovered Error → 正常終了
; $2 Not Ready → リトライ
; $3 Medium Error
; $4 Hardware Error
; $5 Illegal Request
; $6 Unit Attention → リトライ
; $7 Data Protect
; $8 Blank Check
; $9 (ベンダ固有)
; $A Copy Aborted
; $B Aborted Command → リトライ
; $C Equal
; $D Volume Overflow
; $E Miscompare
; $F (Reserved)
; cmp.b #$3,d0 ;Medium Errorを無視してみる
; beq 8f
subq.b #$2,d0
bcs 8f ;$0,$1 → 正常終了
beq 7f ;$2 → リトライ
subq.b #$6-$2,d0
beq 7f ;$6 → リトライ
subq.b #$B-$6,d0
beq 7f ;$B → リトライ
6: moveq.l #-1,d0
bra 9f
7: moveq.l #1,d0
bra 9f
8: moveq.l #0,d0
9: lea.l (256,sp),sp
movem.l (sp)+,d1-d4/a1
rts
.data
scsicmd_error_sts:: .dc.b 0
scsicmd_error_sns:: .dc.b 0
;----------------------------------------------------------------
;SCSIコマンドのエラー状況を表示する
.text
.align 4,$2048
print_scsicmd_error::
movem.l d0/a0-a1,-(sp)
tst.b scsicmd_error_call
beq 99f
lea.l (m_scsicmd_failed_by,pc),a0
bsr eprint
move.b scsicmd_error_call,d0
cmp.b #-1,d0
bne 1f
cmpi.b #$02,scsicmd_error_sts
bne 2f
;Check Condition後のRequest Senseによるエラー
move.b scsicmd_error_sns,d0
lea.l (m_scsicmd_medium_error,pc),a0
subq.b #$3,d0
beq 3f
lea.l (m_scsicmd_hardware_error,pc),a0
subq.b #$4-$3,d0
beq 3f
lea.l (m_scsicmd_illegal_request,pc),a0
subq.b #$5-$4,d0
beq 3f
lea.l (m_scsicmd_check_condition,pc),a0
bsr eprintcrlf
bsr print_scsicmd_error_sns
bra 9f
2: ;Check Condition以外のステータスによるエラー
lea.l (m_scsicmd_error_status,pc),a0
bsr eprintcrlf
bsr print_scsicmd_error_sts
bra 9f
1: cmp.b #-2,d0
bne 1f
lea.l (m_scsicmd_status_busy,pc),a0
cmpi.b #$02,scsicmd_error_sts
bne 3f ;Busyによるリトライオーバーフロー
2: ;Check Condition後のリトライオーバーフロー
lea.l (m_scsicmd_check_condition,pc),a0
bsr eprint
move.b scsicmd_error_sns,d0
lea.l (m_scsicmd_not_ready,pc),a0
subq.b #$2,d0
beq 3f ;Not Readyによるリトライオーバーフロー
lea.l (m_scsicmd_unit_attention,pc),a0
subq.b #$6-$2,d0
beq 3f ;Unit Attentionによるリトライオーバーフロー
lea.l (m_scsicmd_aborted_command,pc),a0
3: bsr eprint
bra 9f
1: lea.l (scsicmd_error_table,pc),a1
1: cmp.b (a1)+,d0
beq 2f
@@: tst.b (a1)+
bne @b
tst.b (a1)
bne 1b
lea.l (m_scsicmd_unknown_call,pc),a1 ;念のため
2: lea.l (m_scsicmd_call,pc),a0
bsr eprint
movea.l a1,a0
3: bsr eprint
lea.l (m_scsicmd_failed,pc),a0
bsr eprintcrlf
lea.l (m_scsicmd_return_code,pc),a0
bsr eprint
move.l scsicmd_error_d0,d0
bsr h8tos_eprint
bsr ecrlf
lea.l (m_scsicmd_retry_count,pc),a0
bsr eprint
moveq.l #0,d0
move.b scsicmd_error_retry,d0
bsr utos_eprint
7: bsr ecrlf
bsr print_scsicmd_error_sts
8: bsr ecrlf
bsr print_scsicmd_error_sns
9: bsr ecrlf
sf.b scsicmd_error_call
99: movem.l (sp)+,d0/a0-a1
rts
print_scsicmd_error_sts:
lea.l (m_scsicmd_status_byte,pc),a0
bsr eprint
moveq.l #0,d0
move.b scsicmd_error_sts,d0
bra h2tos_eprint
print_scsicmd_error_sns:
lea.l (m_scsicmd_sense_key,pc),a0
bsr eprint
moveq.l #0,d0
move.b scsicmd_error_sns,d0
bra h2tos_eprint
m_scsicmd_failed_by: .dc.b 'SCSI operation failed by',0
m_scsicmd_check_condition: .dc.b ' Check Condition',0
m_scsicmd_error_status: .dc.b ' Error Status',0
m_scsicmd_status_busy: .dc.b ' Busy Status',0
m_scsicmd_not_ready: .dc.b ' Not Ready',0
m_scsicmd_medium_error: .dc.b ' Medium Error',0
m_scsicmd_hardware_error: .dc.b ' Hardware Error',0
m_scsicmd_illegal_request: .dc.b ' Illegal Request',0
m_scsicmd_unit_attention: .dc.b ' Unit Attention',0
m_scsicmd_aborted_command: .dc.b ' Aborted Command',0
m_scsicmd_unknown_call: .dc.b ' ???',0
m_scsicmd_call: .dc.b ' ',0
m_scsicmd_failed: .dc.b ' failed',0
m_scsicmd_return_code: .dc.b ' Return Code: $',0
m_scsicmd_retry_count: .dc.b ' Retry Count: ',0
m_scsicmd_status_byte: .dc.b ' Status Byte: $',0
m_scsicmd_sense_key: .dc.b ' Sense Key: $',0
scsicmd_error_table:
.dc.b _S_SELECT,'_S_SELECT',0
.dc.b _S_CMDOUT,'_S_CMDOUT',0
.dc.b _S_DATAIN,'_S_DATAIN',0
.dc.b _S_DATAIN_P,'_S_DATAIN_P',0
.dc.b _S_STSIN,'_S_STSIN',0
.dc.b _S_MSGIN,'_S_MSGIN',0
.dc.b _S_MODESELECT,'_S_MODESELECT',0
.dc.b _S_MODESENSE,'_S_MODESENSE',0
.dc.b 0
.even